﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Linq;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ComicIsland.Common;
using ComicIsland.Common.Entities;
using ComicIsland.Common.Entities.ComicDatabase;

/**
 * 创建时间：2014/12/19 11:52:40
 * 作者：yong.blackcore
 * Email：itblackhole@outlook.com
 * QQ：50404503
 */
namespace ComicIsland.App.Views.DownloadComicViews
{
    public class ComicDatabaseContextHelper
    {
        public static AutoResetEvent dblock = new AutoResetEvent(true);

        //private ComicDatabaseContext comicDb;
        //public ComicDatabaseContextHelper()
        //{
        //    this.comicDb = new ComicDatabaseContext(KEYS.DBConnectionString);                        
        //    if (!comicDb.DatabaseExists())
        //    {
        //        comicDb.CreateDatabase();
        //    }
        //}

        private ComicDatabaseContext comicDb;
        public ComicDatabaseContextHelper(ComicDatabaseContext comicDb)
        {
            this.comicDb = comicDb;
        }

        #region ******************************Comic******************************
        public void OutputTableInfoFromComic()
        {
            var table = this.comicDb.GetTable<DbComic>();
            if (table != null && table.Count() > 0)
            {
                foreach (var item in table)
                {
                    LogHelper.LogInfo(item.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
                }
            }
        }

        public bool ComicIsExist(int comicId)
        {
            if (this.ComicGetOne(comicId) == null)
                return false;
            else
                return true;
        }

        /// <summary>
        /// 获取全部缓存下载的漫画列表
        /// </summary>
        /// <returns></returns>
        public ObservableCollection<DbComic> ComicAllObservableCollection()
        {
            var table = this.comicDb.GetTable<DbComic>();            
            if (table != null && table.Count() > 0)//无记录时，count()方法会报错            
            {
                var list = table.ToList<DbComic>();
                if (list != null && list.Count > 0)
                {
                    return new ObservableCollection<DbComic>(list);
                }
            }
            return null;
        }

        public ObservableCollection<DbComic> ComicObservableCollectionByStatus(DownloadComicChapterStatus status)
        {
            var items = this.ComicAllObservableCollection();
            if (items != null && items.Count() > 0)
            {
                var list = items.Where(p => p.DownloadStatus.Equals(status.ToString())).ToList<DbComic>();
                if (list != null && list.Count > 0)
                {
                    return new ObservableCollection<DbComic>(list);
                }
            }
            return null;
        }

        public bool ComicRemoveByComic(int comicId)
        {
            bool result = false;
            try
            {
                dblock.WaitOne();
                var table = this.comicDb.GetTable<DbComic>();
                if (table != null && table.Count() > 0)
                {
                    var items = table.Where(p => p.ComicId == comicId).ToList<DbComic>();
                    if (items != null && items.Count > 0)
                    {
                        this.comicDb.Comics.DeleteAllOnSubmit(items);
                        this.comicDb.SubmitChanges();
                    }
                }
                result = true;
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }
            return result;
        }


        public DbComic ComicGetOne(int comicId)
        {
            try
            {
                var table = this.comicDb.GetTable<DbComic>();
                if (table != null && table.Count() > 0)
                {
                    return table.Where(p => p.ComicId == comicId).FirstOrDefault<DbComic>();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            return null;
        }

        public void ComicInsert(DbComic comic)
        {
            try
            {
                if (comic == null)
                    return;

                var row = ComicGetOne(comic.ComicId);
                if (row != null)
                {
                    if (!string.IsNullOrWhiteSpace(comic.ComicTitle))
                        row.ComicTitle = comic.ComicTitle;
                    if (!string.IsNullOrWhiteSpace(comic.CoverUrl))
                        row.CoverUrl = comic.CoverUrl;
                    if (!string.IsNullOrWhiteSpace(comic.DownloadStatus))
                        row.DownloadStatus = comic.DownloadStatus;
                }
                else
                {
                    this.comicDb.Comics.InsertOnSubmit(comic);
                }
                this.comicDb.SubmitChanges();
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
        }

        /// <summary>
        /// 更新漫画状态
        /// </summary>
        /// <param name="comicId"></param>
        /// <param name="status"></param>
        public void ComicUpdateStatus(int comicId, DownloadComicChapterStatus status)
        {
            try
            {
                var row = ComicGetOne(comicId);
                if (row != null)
                {
                    row.DownloadStatus = status.ToString();
                    this.comicDb.SubmitChanges();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
        }
        #endregion  ******************************Comic******************************



        #region ******************************Chapter******************************
        public void OutputTableInfoFromComicChapter()
        {
            var table = this.comicDb.GetTable<DbChapter>();
            if (table != null && table.Count() > 0)
            {
                foreach (var item in table)
                {
                    LogHelper.LogInfo(item.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
                }
            }
        }

        public bool ChapterIsExist(int comicId, int chapterId)
        {
            if (this.ChapterGetOne(comicId, chapterId) == null)
                return false;
            else
                return true;
        }
        public DbChapter ChapterGetOne(int comicId, int chapterId)
        {
            try
            {
                var table = this.comicDb.GetTable<DbChapter>();
                if (table != null && table.Count() > 0)
                {
                    return table.Where(p => p.ComicId == comicId && p.PartId == chapterId).FirstOrDefault<DbChapter>();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            return null;
        }

        /// <summary>
        /// 获取某个漫画的所有章节
        /// </summary>
        /// <param name="comicId"></param>
        /// <returns></returns>
        public ObservableCollection<DbChapter> ChapterGetObservableCollectionByComic(int comicId)
        {
            try
            {
                var table = this.comicDb.GetTable<DbChapter>();
                if (table != null && table.Count() > 0)
                {
                    var list = table.Where(p => p.ComicId == comicId).OrderBy(p => p.PartId).ToList<DbChapter>();
                    if (list != null && list.Count > 0)
                    {
                        return new ObservableCollection<DbChapter>(list);
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            return null;
        }

        /// <summary>
        /// 将章节表中所有属于comid的章节全部删除
        /// </summary>
        /// <param name="comicId"></param>
        /// <returns></returns>
        public bool ChapterRemoveByComic(int comicId)
        {
            bool result = false;
            try
            {
                dblock.WaitOne();
                var table = this.comicDb.GetTable<DbChapter>();
                if (table != null && table.Count() > 0)
                {
                    var items = (from p in table where p.ComicId == comicId select p).ToList<DbChapter>();
                    if (items != null && items.Count > 0)
                    {
                        this.comicDb.Chapters.DeleteAllOnSubmit(items);
                        this.comicDb.SubmitChanges();
                    }
                }
                result = true;
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }
            return result;

        }

        public ObservableCollection<DbChapter> ChapterGetObservableCollectionByComic(int comicId, DownloadComicChapterStatus status)
        {
            var items = ChapterGetObservableCollectionByComic(comicId);
            try
            {
                if (items != null && items.Count > 0)
                {
                    var result = (from p in items where status.ToString().Equals(p.DownloadStatus) select p).ToList<DbChapter>();
                    if (result != null && items.Count > 0)
                    {
                        return new ObservableCollection<DbChapter>(result);
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            return null;
        }


        /// <summary>
        /// 获取指定状态的章节数据
        /// </summary>
        /// <param name="status"></param>
        /// <returns></returns>
        public DbChapter ChapterGetByDownloadStatus(DownloadComicChapterStatus status, int comicId = 0)
        {
            try
            {
                dblock.WaitOne();
                var table = this.comicDb.GetTable<DbChapter>();
                if (table != null && table.Count() > 0)
                {
                    return table.Where(p => ((comicId <= 0 ? true : p.ComicId == comicId)) && p.DownloadStatus.Equals(status.ToString())).OrderBy(p => p.PartId).FirstOrDefault<DbChapter>();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }
            return null;
        }

        /// <summary>
        /// 更新漫画状态
        /// </summary>
        /// <param name="comicId"></param>
        /// <param name="status"></param>
        public void ChapterUpdateStatus(int comicId, int chapterId, DownloadComicChapterStatus status)
        {
            try
            {
                var row = this.ChapterGetOne(comicId, chapterId);
                if (row != null)
                {
                    row.DownloadStatus = status.ToString();
                    this.comicDb.SubmitChanges();
                }
                if (DownloadComicChapterStatus.Completed.ToString().Equals(status.ToString()))
                {
                    bool IsAllCompleted = true;
                    var rows = this.ChapterGetObservableCollectionByComic(comicId);
                    if (rows != null && rows.Count > 0)
                    {
                        foreach (var subRow in rows)
                        {
                            if (subRow == null)
                                continue;
                            if (subRow.DownloadStatus.Equals(DownloadComicChapterStatus.Pending) || subRow.DownloadStatus.Equals(DownloadComicChapterStatus.Pending))
                            {
                                IsAllCompleted = false;
                                break;
                            }
                        }
                    }
                    if (IsAllCompleted)
                    {
                        //漫画中的章节全部下载完成，更新漫画下载状态
                        ComicUpdateStatus(comicId, DownloadComicChapterStatus.Completed);
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
        }

        public void ChapterInsert(int comicId, IEnumerable<DbChapter> chapters)
        {
            try
            {
                if (this.ComicIsExist(comicId))
                {
                    this.ComicUpdateStatus(comicId, DownloadComicChapterStatus.Pending);
                }
                if (chapters != null && chapters.Count() > 0)
                {
                    //this.db.Chapters.InsertAllOnSubmit<DbChapter>(chapters);
                    foreach (DbChapter item in chapters)
                    {
                        this.comicDb.Chapters.InsertOnSubmit(item);
                    }
                    this.comicDb.SubmitChanges();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
        }
        #endregion ******************************Chapter******************************


        #region ******************************Image******************************
        public void OutputTableInfoFromComicChapterImage()
        {
            var table = this.comicDb.GetTable<DbImage>();
            if (table != null && table.Count() > 0)
            {
                foreach (var item in table)
                {
                    LogHelper.LogInfo(item.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
                }
            }
        }

        /// <summary>
        /// 获取某漫画中某章节的所有图片信息
        /// </summary>
        /// <param name="comicId"></param>
        /// <param name="chapterId"></param>
        /// <returns></returns>
        public ObservableCollection<DbImage> ImageGetByComicIdAndChapterId(int comicId, int chapterId)
        {
            try
            {
                dblock.WaitOne();
                var table = this.comicDb.GetTable<DbImage>();

                if (table != null && table.Count() > 0)
                {
                    var list = table.Where(p => p.ComicId == comicId && p.PartId == chapterId).ToList<DbImage>();
                    if (list != null && list.Count > 0)
                    {
                        return new ObservableCollection<DbImage>(list);
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }
            return null;
        }

        /// <summary>
        /// 移除所有漫画中的图片信息
        /// </summary>
        /// <param name="comicId"></param>
        /// <returns></returns>
        public bool ImageRemoveByComic(int comicId)
        {
            bool result = false;
            try
            {
                dblock.WaitOne();
                var table = this.comicDb.GetTable<DbImage>();
                if (table != null && table.Count() > 0)
                {
                    var items = (from p in table where p.ComicId == comicId select p).ToList<DbImage>();
                    if (items != null && items.Count > 0)
                    {
                        this.comicDb.Images.DeleteAllOnSubmit(items);
                        this.comicDb.SubmitChanges();
                    }
                }
                result = true;
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }
            return result;
        }

        /// <summary>
        /// 获取指定状态的数据
        /// </summary>
        /// <param name="status"></param>
        /// <returns></returns>
        public DbImage ImageGetOneByDownloadStatus(DownloadComicChapterStatus status, int comicId = 0)
        {
            try
            {
                dblock.WaitOne();
                var table = this.comicDb.GetTable<DbImage>();
                if (table != null && table.Count() > 0)
                {
                    return table.Where(p => (comicId <= 0 ? true : p.ComicId == comicId) && p.DownloadStatus.Equals(status.ToString())).OrderByDescending(p => p.ImageUrl).FirstOrDefault<DbImage>();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }

            return null;
        }


        /// <summary>
        /// 获取一行章节图片信息
        /// </summary>
        /// <param name="comicId"></param>
        /// <param name="chapterId"></param>
        /// <param name="imageUrl"></param>
        /// <returns></returns>
        public DbImage ImageGetOne(int comicId, int chapterId, string imageUrl)
        {
            try
            {
                dblock.WaitOne();
                var table = this.comicDb.GetTable<DbImage>();
                if (table != null && table.Count() > 0)
                {
                    return table.Where(p => p.ComicId == comicId && p.PartId == chapterId && p.ImageUrl.Equals(imageUrl)).FirstOrDefault<DbImage>();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }
            return null;
        }

        /// <summary>
        /// 更新下载状态
        /// <para>递归向上更新</para>
        /// </summary>
        /// <param name="dbImage"></param>
        /// <param name="status"></param>
        public void ImageUpdateStatus(DbImage dbImage, DownloadComicChapterStatus status)
        {
            try
            {
                dblock.WaitOne();
                if (dbImage == null)
                    return;

                //var row = ImageGetOne(dbImage.ComicId, dbImage.PartId, dbImage.ImageUrl);
                var table = this.comicDb.GetTable<DbImage>();
                DbImage row = null;
                if (table != null && table.Count() > 0)
                {
                    row = table.Where(p => p.ComicId == dbImage.ComicId && p.PartId == dbImage.PartId && p.ImageUrl.Equals(dbImage.ImageUrl)).FirstOrDefault<DbImage>();
                }

                if (row != null)
                {
                    row.DownloadStatus = status.ToString();
                    this.comicDb.SubmitChanges();
                }
                dblock.Set();


                if (DownloadComicChapterStatus.Completed.ToString().Equals(status.ToString()))
                {
                    bool IsAllCompleted = true;
                    var rows = ImageGetByComicIdAndChapterId(dbImage.ComicId, dbImage.PartId);
                    if (rows != null && rows.Count > 0)
                    {
                        foreach (var subRow in rows)
                        {
                            if (subRow == null)
                                continue;
                            if (subRow.DownloadStatus.Equals(DownloadComicChapterStatus.Pending) || subRow.DownloadStatus.Equals(DownloadComicChapterStatus.Pending))
                            {
                                IsAllCompleted = false;
                                break;
                            }
                        }
                    }
                    if (IsAllCompleted)
                    {
                        //如果已经下载完成了，更新章节的状态
                        ChapterUpdateStatus(dbImage.ComicId, dbImage.PartId, DownloadComicChapterStatus.Completed);
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
            finally
            {
                dblock.Set();
            }
        }

        /// <summary>
        /// 插入记录
        /// </summary>
        /// <param name="images"></param>
        public void ImageInsertOrUpdate(IEnumerable<DbImage> images)
        {
            try
            {
                if (images != null && images.Count() > 0)
                {
                    //this.comicDb.Images.InsertAllOnSubmit<DbImage>(images);
                    foreach (DbImage item in images)
                    {
                        //this.comicDb.Images.InsertOnSubmit(item);
                        var currentRow = ImageGetOne(item.ComicId, item.PartId, item.ImageUrl);
                        if (currentRow == null)
                            this.comicDb.Images.InsertOnSubmit(item);
                        this.comicDb.SubmitChanges();
                    }
                    //this.comicDb.SubmitChanges();
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
        }
        #endregion ******************************Image******************************

    }
}
